/**
 * @param {number[][]} heights
 * @return {number[][]}
 */
 var pacificAtlantic = function(heights) {
  const m = heights.length;
  const n = heights[0].length;
  const valid = (x, y) => x >= 0 && x < m && y >= 0 && y < n;
  const tag = new Array(m).fill(false).map( _ => new Array(n).fill(0));
  const directions = [[1, 0], [0, 1], [-1, 0], [0, -1]];
  let ret = []
  let x = 0; y = 0;
  function trace(x, y, offset) {
      if(x === 0 || y === 0) {
          tag[x][y] |= (1 << offset);
      }
      if(x === m - 1 || y === n - 1) {
          tag[x][y] |= (1 << offset);
      }
      if((tag[x][y] & (1 << offset)) !== 0) {
          directions.forEach(d => {
              const cx = x + d[0], cy = y + d[1];
              if(valid(cx, cy) && heights[x][y] <= heights[cx][cy] && (tag[cx][cy] & (1 << offset)) === 0) {
                  // console.log(x, y, cx, cy, 1 << offset);
                  tag[cx][cy] |= (1 << offset);
                  trace(cx, cy, offset);
              }
          })
      }

  }
  for(let i = 0; i < m; i++) {
      trace(i, 0, 0);
  }
  for(let i = 0; i < n; i++) {
      trace(0, i, 0);
  }
  for(let i = 0; i < m; i++) {
      trace(i, n - 1, 1);
  }
  for(let i = 0; i < n; i++) {
      trace(m - 1, i, 1);
  }
  for(let i = 0; i < m; i++) {
      for(let j = 0; j < n; j++) {
          if(tag[i][j] === 0b11) {
              ret.push([i, j]);
          }
      }
  }
  // console.log(tag);
  return ret;
};